package cn.funeralobjects.upms.controller;

import cn.funeralobjects.upms.api.PermissionApi;
import cn.funeralobjects.upms.service.*;
import cn.funeralobjects.util.ReactorUtils;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.List;

/**
 * Permission外部管理访问接口
 *
 * @author FuneralObjects
 * Create date: 2020/4/28 2:14 PM
 */
@RestController
@RequestMapping(name = "permission", path = "/permission")
public class PermissionController implements PermissionApi {

    @Resource
    private PermissionService permissionService;
    @Resource
    private RoleService roleService;
    @Resource
    private UserService userService;
    @Resource
    private GroupService groupService;
    @Resource
    private ApiService apiService;


    @PostMapping("/group-user")
    @Override
    public Mono<Void> addGroupUser(@RequestParam @NonNull Integer userId,
                                   @RequestParam @NonNull Integer groupId) {
        return Mono.just(new Integer[]{userId, groupId})
                .filter(arr -> userService.isValid(arr[0]) && groupService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.addUserToGroup(arr[0], arr[1])));
    }

    @PostMapping("/role-user")
    @Override
    public Mono<Void> addRoleUser(@RequestParam @NonNull Integer userId,
                                  @RequestParam @NonNull Integer roleId) {
        return Mono.just(new Integer[]{userId, roleId})
                .filter(arr -> userService.isValid(arr[0]) && roleService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.addRoleToUser(arr[1], arr[0])));
    }

    @DeleteMapping("/role-user")
    @Override
    public Mono<Void> removeRoleUser(@RequestParam @NonNull Integer userId,
                                     @RequestParam @NonNull Integer roleId) {
        return Mono.just(new Integer[]{userId, roleId})
                .filter(arr -> userService.isValid(arr[0]) && roleService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.removeRoleFromUser(arr[0], arr[1])));
    }

    @DeleteMapping("/group-user")
    @Override
    public Mono<Void> removeGroupUser(@RequestParam @NonNull Integer userId,
                                      @RequestParam @NonNull Integer groupId) {
        return Mono.just(new Integer[]{userId, groupId})
                .filter(arr -> userService.isValid(arr[0]) && groupService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.removeUserFromGroup(arr[1], arr[0])));
    }

    @PostMapping("/api-role")
    @Override
    public Mono<Void> addApiRole(@RequestParam Integer roleId,
                                 @RequestParam Integer apiId) {
        return Mono.just(new Integer[]{roleId, apiId})
                .filter(arr -> roleService.isValid(arr[0]) && apiService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.addRoleToApi(arr[0], arr[1])));
    }


    @DeleteMapping("/api-role")
    @Override
    public Mono<Void> removeApiRole(@RequestParam Integer roleId,
                                    @RequestParam Integer apiId) {
        return Mono.just(new Integer[]{roleId, apiId})
                .filter(arr -> roleService.isValid(arr[0]) && apiService.isValid(arr[1]))
                .flatMap(ReactorUtils.thenEmpty(arr -> permissionService.removeRoleFromApi(arr[0], arr[1])));
    }

    @GetMapping("/role/apis")
    @Override
    public Mono<List<Integer>> getApisFromRole(@RequestParam Integer roleId) {
        return Mono.just(roleId)
                .filter(roleService::isValid)
                .map(permissionService::findApiIdFromRoleId);
    }

    @GetMapping("/user/roles")
    @Override
    public Mono<List<Integer>> getRolesFromUser(@RequestParam Integer userId) {
        return Mono.just(userId)
                .filter(userService::isValid)
                .map(permissionService::findRoleIdFromUserId);
    }

    @GetMapping("/role/users")
    @Override
    public Mono<List<Integer>> getUsersFromRole(@RequestParam Integer roleId) {
        return Mono.just(roleId)
                .filter(roleService::isValid)
                .map(permissionService::findUserIdFromRoleId);
    }
}
